home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-30 | 14.4 KB | 508 lines | [TEXT/CWIE] |
- // ===========================================================================
- // LAGAIndexTab.cp
- // ===========================================================================
- // “Apple Grayscale Appearance” compliant Index Tabs
- // Copyright © 1996 Chrisoft (Christophe ANDRES) All rights reserved.
- //
- // You may use this source code in any application (commercial, shareware, freeware,
- // postcardware, etc), but not remove this notice (no need to acknowledge the use of
- // this class in the about box)
- // You may not sell this source code in any form. This source code may be placed on
- // publicly accessable archive sites and source code disks. It may not be placed on
- // profit archive sites and source code disks without the permission of the author,
- // Christophe ANDRES.
- //
- // This source code is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- //
- // If you make any change or improvement on this class, please send the improved/changed
- // version to : chrisoft@calva.net or Christophe ANDRES
- // 20, rue Prosper Mérimée
- // 67100 STRASBOURG
- // FRANCE
- //
- // ===========================================================================
- // LAGAIndexTab.h <- double-click + Command-D to see classes declaration
- //
- // LAGAIndexTab is my implementation of the “Apple Grayscale Appearance for System 7.5”
- // Index Tabs. Index Tabs where not defined in this document, but some pictures where
- // found in the March 1996 issue of “Apple Directions” pages 16 and 18.
- // LAGAIndexTab relies on view scrolling to perform its switch between differents tabs.
- // mTabbedViewID is a reference to a view that is embeddedin the LAGAIndexTab.
- // This tabbed view has to be placed at least at 21 pixels from the top of LAGAIndexTab,
- // and must leave at least 1 pixel on each side (left, right and bottom).
- // the LAGAIndexTab will use the vertical scroll unit of the tabbed view to perform its
- // tab switch (adapt also the image size height accordingly).
- // This means that all tab elements are always present (although only one is visible)
- // and the switch between tabs is very fast.
- //
- // Index Tabs are not suitable for large number of tabs, so LAGAIndexTab will display only
- // the Index Tabs fitting in the view size.
- //
- // An alternate way of using the index tabs is by NOT setting mTabbedViewID (nil) and to
- // override LAGAIndexTab::AdaptTab to perform whatever is needed
- //
- // LSTRxAGAIndexTab is a subclass of LAGAIndexTab, which reads the name of its tabs from a
- // 'STR#' resource
- //
- // This class requires AGAColors.cp to be present in your project
- //
- //
- // Version : 1.2
- //
- // Change History (most recent first, date in US form : mm/dd/yy):
- //
- // 06/30/96 ca Public release of version 1.2
- // 06/04/96 ca Added RegisterClass method to ease registry
- // Increased version to 1.2
- // 05/16/96 ca Increased version to 1.1
- // Replaced UEnvironment::HasFeature(env_SupportsColor) with PaneInColor
- // Added change history
- // 04/22/96 ca class made available by Christophe ANDRES <chrisoft@calva.net>
- // (version 1.0)
- //
- // To Do:
- // Remove hardcoded maximum tabs and use some sort of dynamic list
- //
-
-
- #include "LAGAIndexTab.h"
- #include "AGAColors.h"
- #include <URegistrar.h>
- #include <LStream.h>
-
- //-------Private constants--------------------------------------------------------------------------------------------
-
- #define kTagHeigth 20
- #define kTagTextPosition 15
- #define kTagWidthOffset 40 // Leave 20 pixels on each side of the selected title
-
- //------Global initialization-----------------------------------------------------------------------------------------
-
- void RegisterAGAIndexTab ()
-
- {
- // Registration of LAGAIndexTab
- LAGAIndexTab::RegisterClass();
- // Registration of LSTRxIndexTabView
- URegistrar::RegisterClass(LSTRxAGAIndexTab::class_ID, (ClassCreatorFunc)LSTRxAGAIndexTab::CreateSTRxAGAIndexTabStream);
- }
-
- // begin <06/04/96 ca>
- void LAGAIndexTab::RegisterClass ()
-
- {
- URegistrar::RegisterClass(LAGAIndexTab::class_ID, (ClassCreatorFunc)LAGAIndexTab::CreateAGAIndexTabStream);
- }
- // end <06/04/96 ca>
-
- LAGAIndexTab* LAGAIndexTab::CreateAGAIndexTabStream (LStream *inStream)
-
- {
- return (new LAGAIndexTab(inStream));
- }
-
- //-------Constructors-------------------------------------------------------------------------------------------------
-
- LAGAIndexTab::LAGAIndexTab ()
-
- {
- this->InitIndexTab();
-
- mTabbedViewID = 0;
- mTextTraitsID = -1;
- }
-
- LAGAIndexTab::LAGAIndexTab (LStream *inStream) : LView(inStream)
-
- {
- UInt32 theData;
-
- inStream->ReadData(&theData, sizeof(UInt32));
- mTabbedViewID = theData;
- inStream->ReadData(&mTextTraitsID, sizeof(ResIDT));
-
- this->InitIndexTab();
- }
-
- void LAGAIndexTab::InitIndexTab ()
-
- {
- mTabNumber = 1; // There is always at least one index tab
- mWasSelectedTab = -1;
- mSelectedTab = 0;
- mTabTitle[0] = "\p";
- for (int i = 0;i < kMaxTabs; i++)
- mTabTitleWidth[i] = -1; // -1 means that the width has to be calculated again
- }
-
- //-------Drawers----------------------------------------------------------------------------------------------------
-
- void LAGAIndexTab::DrawSelf ()
-
- {
- Boolean hasColor = ::PaneInColor(this); // <05/16/96 ca>
-
- if (IsVisible())
- {
- StColorPenState theState;
- Rect workRect;
- StTextState theTState;
-
- // set our font informations
- Int16 just = UTextTraits::SetPortTextTraits(mTextTraitsID);
-
- // Check if we need to calculate the withs of the index tabs
- for (int i = 0;i < mTabNumber; i++)
- if (mTabTitleWidth[i] == -1)
- {
- this->CalculateTitleWidths();
- break;
- }
-
- theState.Normalize();
- CalcLocalFrameRect(workRect);
- workRect.bottom--;
- workRect.right--;
-
- // First lets draw the rest of the frame, excluding the tabs
- ::MoveTo(workRect.left, workRect.top + kTagHeigth + 1);
- ::LineTo(workRect.left, workRect.bottom - 2);
- ::MoveTo(workRect.left + 1, workRect.bottom -1);
- ::LineTo(workRect.right - 1, workRect.bottom -1);
- ::LineTo(workRect.right - 1, workRect.top + kTagHeigth + 1);
- ::MoveTo(workRect.right - 2, workRect.top + kTagHeigth);
- ::LineTo(workRect.left + 1, workRect.top + kTagHeigth);
-
- if (hasColor)
- {
- ::ForeColor(whiteColor);
- ::MoveTo(workRect.left + 1, workRect.bottom - 2);
- ::LineTo(workRect.left + 1, workRect.top + kTagHeigth + 1);
- ::LineTo(workRect.right - 3, workRect.top + kTagHeigth + 1);
-
- ::RGBForeColor(&gAGAColorArray[8]);
- ::MoveTo(workRect.left + 2, workRect.bottom);
- ::LineTo(workRect.right - 1, workRect.bottom);
- ::MoveTo(workRect.right, workRect.bottom - 1);
- ::LineTo(workRect.right, workRect.top + kTagHeigth + 2);
-
- ::RGBForeColor(&gAGAColorArray[4]);
- ::MoveTo(workRect.left + 2, workRect.bottom - 2);
- ::LineTo(workRect.right - 2, workRect.bottom - 2);
- ::LineTo(workRect.right - 2, workRect.top + kTagHeigth + 1);
- }
-
- // Then let's draw the tab index frames
- short theLeft = workRect.left + 3;
- short theTop = workRect.top + 1;
- short theRight;
- short theWidth;
- short theTextPos;
- short insideColor;
- short color;
- Rect r;
-
- for (int i = 0;i < mTabNumber; i++)
- {
- theWidth = mTabTitleWidth[i];
- if ((theLeft + theWidth) > workRect.right) // Limit the number of tabs if not enough room to display them
- {
- mTabNumber = i;
- break;
- }
- theRight = theLeft + theWidth;
- // Fill the background
- PolyHandle thePoly = ::OpenPoly();
- ::MoveTo(theLeft + 1, theTop + kTagHeigth - 1);
- ::LineTo(theLeft + 7, theTop + 1);
- ::LineTo(theRight - 9,theTop + 1);
- ::LineTo(theRight - 1, theTop + kTagHeigth - 1);
- ::LineTo(theLeft + 1, theTop + kTagHeigth - 1);
- ::ClosePoly();
- if (hasColor)
- if (i == mSelectedTab)
- ::RGBBackColor(&gAGAColorArray[2]);
- else
- ::RGBBackColor(&gAGAColorArray[4]);
- ::ErasePoly(thePoly);
- ::KillPoly(thePoly);
- // Draw the frame
- ::ForeColor(blackColor);
- ::MoveTo(theLeft, theTop + kTagHeigth - 1);
- ::Line(0, -1);
- for (register int i = 0; i < 5; i++)
- {
- ::Move(1, -1);
- ::Line(0, -2);
- }
- ::Line(3, -3);
- ::MoveTo(theRight - 9, theTop);
- ::Line(3, 3);
- ::Line(0, 2);
- for (register int i = 0; i < 4; i++)
- {
- ::Move(1, 1);
- ::Line(0, 2);
- }
- ::Move(1, 1);
- ::Line(0, 1);
- ::ForeColor(whiteColor);
- ::MoveTo(theLeft + 1, theTop + kTagHeigth - 1);
- ::Line(0, -1);
- for (register int i = 0; i < 5; i++)
- {
- ::Move(1, -1);
- ::Line(0, -2);
- }
- ::Line(2, -2);
- if (hasColor)
- {
- ::RGBForeColor(&gAGAColorArray[8]);
- ::MoveTo(theRight - 9, theTop + 1);
- ::Line(2, 2);
- ::Line(0, 2);
- for (register int i = 0; i < 4; i++)
- {
- ::Move(1, 1);
- ::Line(0, 2);
- }
- ::Move(1, 1);
- ::Line(0, 1);
- ::MoveTo(theRight - 8, theTop);
- ::Line(3, 3);
- ::Line(0, 2);
- for (register int i = 0; i < 4; i++)
- {
- ::Move(1, 1);
- ::Line(0, 2);
- }
- }
-
- ::ForeColor(blackColor);
- ::MoveTo(theLeft + 9, theTop);
- ::LineTo(theRight - 10, theTop);
- if (i == mSelectedTab)
- {
- if (hasColor)
- ::RGBForeColor(&gAGAColorArray[2]);
- else
- ::ForeColor(whiteColor);
- ::MoveTo(theLeft + 2, theTop + kTagHeigth - 1);
- }
- else
- ::MoveTo(theLeft + 1, theTop + kTagHeigth - 1);
- ::LineTo(theRight - 2, theTop + kTagHeigth - 1);
- if (i != mSelectedTab)
- ::ForeColor(whiteColor);
- ::MoveTo(theLeft + 2, theTop + kTagHeigth);
- ::LineTo(theRight - 2, theTop + kTagHeigth);
-
- ::ForeColor(whiteColor);
- ::MoveTo(theLeft + 9, theTop + 1);
- ::LineTo(theRight - 10, theTop + 1);
-
- theTextPos = workRect.top + kTagTextPosition;
-
- // Draw the Text into the tab
- DrawText(mTabTitle[i], theLeft, theWidth, theTextPos);
-
- theLeft += theWidth;
- }
- }
- }
-
- void LAGAIndexTab::DrawText (LStr255 &inText, short inLeftBorder, short inTagWidth, short inTextPos)
-
- {
- ::ForeColor(blackColor);
- ::MoveTo(inLeftBorder + ((inTagWidth - ::StringWidth(inText)) / 2), inTextPos);
- ::DrawString(inText);
- }
-
- //-------Utilities--------------------------------------------------------------------------------------------------
-
- void LAGAIndexTab::CalculateTitleWidths ()
-
- {
- StTextState theTState;
-
- Int16 just = UTextTraits::SetPortTextTraits(mTextTraitsID);
- short theLeft = 0;
- for (int i = 0; i <= mTabNumber; i++)
- {
- mTabTitleWidth[i] = ::StringWidth(mTabTitle[i]) + kTagWidthOffset;
- mTabLeftPositions[i] = theLeft;
- theLeft += mTabTitleWidth[i] + 1;
- }
- }
-
- void LAGAIndexTab::SetTabTitle (short inTab, LStr255& inTitle)
-
- {
- if (inTab < mTabNumber)
- {
- mTabTitle[inTab] = inTitle;
- mTabTitleWidth[inTab] = -1;
- }
- }
-
- void LAGAIndexTab::GetTabTitle (short inTab, LStr255& outTitle)
-
- {
- if (inTab < mTabNumber)
- outTitle = mTabTitle[inTab];
- else
- outTitle = "\p";
- }
-
- Boolean LAGAIndexTab::SetTabCount (short inCount)
-
- {
- Boolean result = false;
-
- if (inCount <= kMaxTabs)
- {
- mTabNumber = inCount;
- // for security reasons, force a recalculation of the index tabs on next redraw
- for (int i = 0;i < kMaxTabs; i++)
- mTabTitleWidth[i] = -1;
- result = true;
- }
- return(result);
- }
-
- void LAGAIndexTab::SetSelectedTab (short inTab)
-
- {
- if (inTab < mTabNumber)
- {
- if (inTab != mSelectedTab)
- {
- mWasSelectedTab = mSelectedTab;
- mSelectedTab = inTab;
-
- Rect tabRect;
- Point *thePt;
- ::SetRect(&tabRect, mTabLeftPositions[mWasSelectedTab] - 2, 0,
- mTabLeftPositions[mWasSelectedTab] + mTabTitleWidth[mWasSelectedTab] + 3, kTagHeigth + 2);
- thePt = (Point *)&tabRect;
- LocalToPortPoint(*thePt);
- thePt++;
- LocalToPortPoint(*thePt);
- InvalPortRect(&tabRect);
- ::SetRect(&tabRect, mTabLeftPositions[mSelectedTab] - 2, 0,
- mTabLeftPositions[mSelectedTab] + mTabTitleWidth[mSelectedTab] + 5, kTagHeigth + 2);
- thePt = (Point *)&tabRect;
- LocalToPortPoint(*thePt);
- thePt++;
- LocalToPortPoint(*thePt);
- InvalPortRect(&tabRect);
-
- AdaptTab();
- LCommander::SetUpdateCommandStatus(true); // Force the menus to update (in case some menu keep track of our tabs)
- }
- }
- }
-
- short LAGAIndexTab::GetSelectedTab ()
-
- {
- return(mSelectedTab);
- }
-
- void LAGAIndexTab::EventMouseUp (const EventRecord &inMouseUp)
-
- {
- LView::EventMouseUp(inMouseUp);
-
- Rect theTag;
- Point thePt;
-
- thePt = inMouseUp.where;
- GlobalToPortPoint(thePt);
- PortToLocalPoint(thePt);
- for (int i = 0;i < mTabNumber; i++)
- {
- ::SetRect(&theTag, mTabLeftPositions[i], (mSelectedTab == i) ? 0 : 2, mTabLeftPositions[i] + mTabTitleWidth[i], kTagHeigth);
- if (::PtInRect(thePt, &theTag))
- {
- this->SetSelectedTab(i);
- break;
- }
- }
- }
-
- void LAGAIndexTab::AdaptTab (Boolean inRefresh)
-
- {
- if (mTabbedViewID)
- {
- LView *theView = (LView *)FindPaneByID(mTabbedViewID);
- if (theView)
- {
- SPoint32 theUnit;
-
- theView->GetScrollUnit(theUnit);
- theView->ScrollImageTo(0, mSelectedTab * theUnit.v, inRefresh);
- }
- }
- }
-
- void LAGAIndexTab::FinishCreateSelf ()
-
- {
- this->AdaptTab(false);
- }
-
- //-------LSTRxIndexTabView implementation-----------------------------------------------------------------------------
-
- // begin <06/04/96 ca>
- void LSTRxAGAIndexTab::RegisterClass ()
-
- {
- URegistrar::RegisterClass(LSTRxAGAIndexTab::class_ID, (ClassCreatorFunc)LSTRxAGAIndexTab::CreateSTRxAGAIndexTabStream);
- }
- // end <06/04/96 ca>
-
- LSTRxAGAIndexTab* LSTRxAGAIndexTab::CreateSTRxAGAIndexTabStream (LStream *inStream)
-
- {
- return (new LSTRxAGAIndexTab(inStream));
- }
-
- //-------Constructors-------------------------------------------------------------------------------------------------
-
- LSTRxAGAIndexTab::LSTRxAGAIndexTab (LStream *inStream) : LAGAIndexTab(inStream)
-
- {
- short theSTRxID;
-
- inStream->ReadData(&theSTRxID, sizeof(theSTRxID));
-
- this->InitSTRxIndexTab(theSTRxID);
- }
-
- void LSTRxAGAIndexTab::InitSTRxIndexTab (short inSTRxID)
-
- {
- Handle theHandle = GetResource('STR#', inSTRxID);
- if (theHandle)
- {
- short theCount = **((short **)theHandle);
- ReleaseResource(theHandle);
- if (theCount > kMaxTabs)
- theCount = kMaxTabs;
- this->SetTabCount(theCount);
- for (int i = 0;i < theCount; i++)
- {
- LStr255 theString;
-
- GetIndString(theString, inSTRxID, i + 1);
- this->SetTabTitle(i, theString);
- }
- }
- }
-
-